package com.jwaoo.chat.session.list;

import android.app.Activity;
import android.content.Intent;
import android.os.Build;
import android.os.Handler;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;

import com.dx.as.common.ILoadListener;
import com.dx.as.common.string.StringUtil;
import com.dx.as.common.sys.ClipboardUtil;
import com.dx.as.db.IDBListener;
import com.dx.as.db.SqlLiteHelper;
import com.dx.as.upload.DownloadManager;
import com.dx.as.upload.OnDownloadListener;
import com.jwaoo.chat.ChatConstants;
import com.jwaoo.chat.Message;
import com.jwaoo.chat.R;
import com.jwaoo.chat.attachment.FileAttachment;
import com.jwaoo.chat.data.db.ChatDatabase;
import com.jwaoo.chat.data.db.MessageHandler;
import com.jwaoo.chat.session.actions.Container;
import com.jwaoo.chat.session.audio.MessageAudioControl;
import com.jwaoo.chat.ui.recyclerview.holder.BaseFetchLoadAdapter;
import com.jwaoo.chat.ui.recyclerview.loadmore.MsgListFetchLoadMoreView;
import com.jwaoo.media.dialog.CustomAlertDialog;
import com.jwaoo.media.dialog.EasyAlertDialog;
import com.jwaoo.media.dialog.EasyAlertDialogHelper;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;

/**
 * 基于RecyclerView的消息收发模块
 * Created by huangjun on 2016/12/27.
 */
public class MessageListPanelEx {
    private static final int REQUEST_CODE_FORWARD_PERSON = 0x01;
    private static final int REQUEST_CODE_FORWARD_TEAM = 0x02;
    private Container container;
    // message list view
    private RecyclerView messageListView;
    // 新消息到达提醒
    private IncomingMsgPrompt incomingMsgPrompt;
    private Handler uiHandler;
    private List<Message> items;
    private MsgAdapter adapter;
    private boolean recordOnly;
    private boolean remote;
    private Message anchor;
    private MessageHandler messageHandler;

    public MessageListPanelEx(Container container, boolean recordOnly, boolean remote) {
        this(container, null, recordOnly, remote);
    }

    public MessageListPanelEx(Container container, Message anchor, boolean recordOnly, boolean remote) {
        this.container = container;
        this.recordOnly = recordOnly;
        this.remote = remote;
        this.anchor = anchor;
        this.messageHandler = MessageHandler.getInstace(container.activity.getApplicationContext());
        init(anchor);
    }
    public void reload(Container container, Message anchor) {
        this.container = container;
        if (adapter != null) {
            adapter.clearData();
        }

        initFetchLoadListener(anchor);
    }
    private void init(Message message){
        initListView();
        this.uiHandler = new Handler();
        if (!recordOnly) {
            incomingMsgPrompt = new IncomingMsgPrompt(container.activity, messageListView, adapter, uiHandler);
        }
    }

    private void initListView(){
        // RecyclerView
        messageListView = (RecyclerView) this.container.activity.findViewById(R.id.messageListView);
        messageListView.setLayoutManager(new LinearLayoutManager(container.activity));
        messageListView.requestDisallowInterceptTouchEvent(true);
        messageListView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                if (newState != RecyclerView.SCROLL_STATE_IDLE) {
                    container.proxy.shouldCollapseInputPanel();
                }
            }
        });
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
            messageListView.setOverScrollMode(View.OVER_SCROLL_NEVER);
        }

        // adapter
        items = new ArrayList<>();
        adapter = new MsgAdapter(messageListView, items);
        adapter.setFetchMoreView(new MsgListFetchLoadMoreView());
        adapter.setLoadMoreView(new MsgListFetchLoadMoreView());
        adapter.setEventListener(new MsgItemEventListener());
        initFetchLoadListener(anchor);
        messageListView.setAdapter(adapter);
    }

    private void initFetchLoadListener(Message anchor) {
        MessageLoader loader = new MessageLoader(anchor, remote);

        if (recordOnly && !remote) {
            // 双向Load
            adapter.setOnFetchMoreListener(loader);
            adapter.setOnLoadMoreListener(loader);
        } else {
            // 只下来加载old数据
            adapter.setOnFetchMoreListener(loader);
        }
    }

    // 刷新消息列表
    public void refreshMessageList(Message message) {
        if (adapter.getData().contains(message)){
            final int index = adapter.getData().indexOf(message);
            adapter.getData().remove(index);
            adapter.getData().add(index,message);
            uiHandler.post(new Runnable() {
                @Override
                public void run() {
                    adapter.notifyItemChanged(index);
                }
            });

        }
        container.activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                adapter.notifyDataSetChanged();
            }
        });
    }



    /**
     * *************** MessageLoader ***************
     */
    private class MessageLoader implements BaseFetchLoadAdapter.RequestLoadMoreListener, BaseFetchLoadAdapter.RequestFetchMoreListener {

        private static final int LOAD_MESSAGE_COUNT = 10;

        private boolean firstLoad = true;


        public MessageLoader(Message anchor,boolean remote) {
            loadFromLocal();
        }


        private void loadFromLocal() {
            long time = 0;
            int size = adapter.getDataSize();
            if ( size > 0){
                try{
                    time = adapter.getData().get(0).getTimestamp();
                    Log.e("===",""+adapter.getData().get(size - 1).getTimestamp());
                    Log.e("===",""+time);
                }catch (Exception ex){
                    ex.printStackTrace();
                }
            }
            messageHandler.handlerMessages(MessageHandler.GET_MESSAGE, container.account, new ILoadListener<Object>() {
                @Override
                public void onResponse(Object response, int flg) {
                    if (response != null){
                        final List<Message> list = (List<Message>)response;
                        uiHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                onMessageLoaded(list);
                            }
                        });


                    }
                }
                @Override
                public void onFailure(Throwable t) {

                }
            },time);
        }

        /**
         * 历史消息加载处理
         */
        private void onMessageLoaded(List<Message> messages) {
            int count = messages.size();

            // 逆序
            Collections.reverse(messages);
            // 加入到列表中
            if (count <= 0) {
                adapter.fetchMoreEnd(true);
            } else {
                adapter.fetchMoreComplete(messageListView, messages);
            }

            // 如果是第一次加载，updateShowTimeItem返回的就是lastShowTimeItem
            if (firstLoad) {
                doScrollToBottom();
            }

            firstLoad = false;
        }

        @Override
        public void onFetchMoreRequested() {
            loadFromLocal();
        }

        @Override
        public void onLoadMoreRequested() {
            loadFromLocal();
        }
    }

    private class MsgItemEventListener implements MsgAdapter.ViewHolderEventListener {

        @Override
        public void onFailedBtnClick(Message message) {
            if (message.getDirect() == ChatConstants.Out) {
                // 发出的消息，如果是发送失败，直接重发，否则有可能是漫游到的多媒体消息，但文件下载
                if (message.getState() == ChatConstants.fail) {
                    resendMessage(message); // 重发
                } else {
                    if (message.getAttachment() instanceof FileAttachment) {
                        FileAttachment attachment = (FileAttachment) message.getAttachment();
                        if (TextUtils.isEmpty(attachment.getPath())
                                && TextUtils.isEmpty(attachment.getThumbPath())) {
                            showReDownloadConfirmDlg(message);
                        }
                    } else {
                        resendMessage(message);
                    }
                }
            } else {
                showReDownloadConfirmDlg(message);
            }
        }

        @Override
        public boolean onViewHolderLongClick(View clickView, View viewHolderView, Message item) {
            if (container.proxy.isLongClickEnabled()) {
                showLongClickAction(item);
            }
            return true;
        }

        // 重新下载(对话框提示)
        private void showReDownloadConfirmDlg(final Message message) {
            EasyAlertDialogHelper.OnDialogActionListener listener = new EasyAlertDialogHelper.OnDialogActionListener() {

                @Override
                public void doCancelAction() {
                }

                @Override
                public void doOkAction() {
                    // 正常情况收到消息后附件会自动下载。如果下载失败，可调用该接口重新下载
                    if (message.getAttachment() != null && message.getAttachment() instanceof FileAttachment){

                    }
                }
            };

            final EasyAlertDialog dialog = EasyAlertDialogHelper.createOkCancelDiolag(container.activity, null,
                    container.activity.getString(R.string.repeat_download_message), true, listener);
            dialog.show();
        }

        // 重发消息到服务器
        private void resendMessage(Message message) {
            // 重置状态为unsent
            int index = getItemIndex(message.get_id()+"");
            if (index >= 0 && index < items.size()) {
                Message item = items.get(index);
                item.setState(ChatConstants.sending);
                onMsgSend(item);
            }
            //发送消息
//            NIMClient.getService(MsgService.class).sendMessage(message, true);
        }

        /**
         * ****************************** 长按菜单 ********************************
         */

        // 长按消息Item后弹出菜单控制
        private void showLongClickAction(Message selectedItem) {
            onNormalLongClick(selectedItem);
        }

        /**
         * 长按菜单操作
         *
         * @param item
         */
        private void onNormalLongClick(Message item) {
            CustomAlertDialog alertDialog = new CustomAlertDialog(container.activity);
            alertDialog.setCancelable(true);
            alertDialog.setCanceledOnTouchOutside(true);

            prepareDialogItems(item, alertDialog);
            alertDialog.show();
        }

        // 长按消息item的菜单项准备。如果消息item的MsgViewHolder处理长按事件(MsgViewHolderBase#onItemLongClick),且返回为true，
        // 则对应项的长按事件不会调用到此处
        private void prepareDialogItems(final Message selectedItem, CustomAlertDialog alertDialog) {
            int msgType = selectedItem.getMsgtype();

            MessageAudioControl.getInstance(container.activity).stopAudio();

            // 0 EarPhoneMode
            longClickItemEarPhoneMode(alertDialog, msgType);
            // 1 resend
            longClickItemResend(selectedItem, alertDialog);
            // 2 copy
            longClickItemCopy(selectedItem, alertDialog, msgType);

            //转发 ，判断消息是否为可转发类型
            if (!recordOnly) {
                // 6 forward to person
                longClickItemForwardToPerson(selectedItem, alertDialog);
            }
        }

        // 长按菜单项--重发
        private void longClickItemResend(final Message item, CustomAlertDialog alertDialog) {
            if (item.getState() != ChatConstants.fail) {
                return;
            }
            alertDialog.addItem(container.activity.getString(R.string.repeat_send_has_blank), new CustomAlertDialog.onSeparateItemClickListener() {

                @Override
                public void onClick() {
                    onResendMessageItem(item);
                }
            });
        }

        private void onResendMessageItem(Message message) {
            int index = getItemIndex(message.get_id()+"");
            if (index >= 0) {
                showResendConfirm(message, index); // 重发确认
            }
        }

        private void showResendConfirm(final Message message, final int index) {
            EasyAlertDialogHelper.OnDialogActionListener listener = new EasyAlertDialogHelper.OnDialogActionListener() {

                @Override
                public void doCancelAction() {
                }

                @Override
                public void doOkAction() {
                    resendMessage(message);
                }
            };
            final EasyAlertDialog dialog = EasyAlertDialogHelper.createOkCancelDiolag(container.activity, null,
                    container.activity.getString(R.string.repeat_send_message), true, listener);
            dialog.show();
        }

        // 长按菜单项--复制
        private void longClickItemCopy(final Message item, CustomAlertDialog alertDialog, int msgType) {
            if (msgType != ChatConstants.text) {
                return;
            }
            alertDialog.addItem(container.activity.getString(R.string.copy_has_blank), new CustomAlertDialog.onSeparateItemClickListener() {

                @Override
                public void onClick() {
                    onCopyMessageItem(item);
                }
            });
        }

        private void onCopyMessageItem(Message item) {
            ClipboardUtil.clipboardCopyText(container.activity, item.getMsg());
        }

        // 长按菜单项 -- 听筒扬声器切换
        private void longClickItemEarPhoneMode(CustomAlertDialog alertDialog, int msgType) {
            if (msgType != ChatConstants.audio) return;

        }

        // 长按菜单项 -- 转发到个人
        private void longClickItemForwardToPerson(final Message item, CustomAlertDialog alertDialog) {
            alertDialog.addItem(container.activity.getString(R.string.forward_to_person), new CustomAlertDialog.onSeparateItemClickListener() {

                @Override
                public void onClick() {

                }
            });
        }
    }

    private int getItemIndex(String uuid) {
        for (int i = 0; i < items.size(); i++) {
            Message message = items.get(i);
            if (TextUtils.equals(message.get_id()+"", uuid)) {
                return i;
            }
        }

        return -1;
    }

    private void doScrollToBottom() {
        messageListView.scrollToPosition(adapter.getBottomDataPosition());
    }

    // 发送消息后，更新本地消息列表
    public void onMsgSend(final Message message) {
        List<Message> addedListItems = new ArrayList<>(1);
        addedListItems.add(message);
        adapter.updateShowTimeItem(addedListItems, false, true);
        adapter.appendData(message);
        doScrollToBottom();

        if ((message.getMsgtype() == ChatConstants.video || message.getMsgtype() == ChatConstants.image || message.getMsgtype() == ChatConstants.snap) && message.getDirect() == ChatConstants.Out) {
            MessageHandler.getInstace(container.activity.getApplicationContext()).uploadAttachmentMessage(message);
            DownloadManager.addDownloadListener(message.get_id(),new OnDownloadListener(){
                int index = adapter.getData().indexOf(message);
                @Override
                public void onDownloadFailed() {
                    message.setState(ChatConstants.fail);
                    message.setAttachState(ChatConstants.fail);
                }

                @Override
                public void onDownSuccess() {
                    message.setState(ChatConstants.success);
                    message.setAttachState(ChatConstants.transferred);
                }

                @Override
                public void onDownProgress(final long progress,final long total) {
                    uiHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            adapter.putProgress(message,(progress * 100L / total));
                            adapter.notifyItemChanged(index);
                        }
                    });
                }
            });
        }
    }

    /**
     * **************************** 排序 ***********************************
     */
    private void sortMessages(List<Message> list) {
        if (list.size() == 0) {
            return;
        }
        Collections.sort(list, comp);
    }

    private static Comparator<Message> comp = new Comparator<Message>() {

        @Override
        public int compare(Message o1, Message o2) {
            long time = o1.getTimestamp() - o2.getTimestamp();
            return time == 0 ? 0 : (time < 0 ? -1 : 1);
        }
    };

    public void onIncomingMessage(List<Message> messages) {
        boolean needScrollToBottom = isLastMessageVisible();
        boolean needRefresh = false;
        List<Message> addedListItems = new ArrayList<>(messages.size());
        for (Message message : messages) {
            items.add(message);
            addedListItems.add(message);
            needRefresh = true;
        }
        if (needRefresh) {
            sortMessages(items);
            adapter.notifyDataSetChanged();
        }

        adapter.updateShowTimeItem(addedListItems, false, true);

        // incoming messages tip
        Message lastMsg = messages.get(messages.size() - 1);
        if (needScrollToBottom) {
            doScrollToBottom();
        } else if (incomingMsgPrompt != null) {
            incomingMsgPrompt.show(lastMsg);
        }
    }

    private boolean isLastMessageVisible() {
        LinearLayoutManager layoutManager = (LinearLayoutManager) messageListView.getLayoutManager();
        int lastVisiblePosition = layoutManager.findLastCompletelyVisibleItemPosition();
        return lastVisiblePosition >= adapter.getBottomDataPosition();
    }

    public void scrollToBottom() {
        uiHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                doScrollToBottom();
            }
        }, 200);
    }

//    public void onActivityResult(int requestCode, int resultCode, Intent data) {
//        if (resultCode != Activity.RESULT_OK) {
//            return;
//        }
//        final ArrayList<String> selected = data.getStringArrayListExtra(ContactSelectActivity.RESULT_DATA);
//        if (selected != null && !selected.isEmpty()) {
//            switch (requestCode) {
//                case REQUEST_CODE_FORWARD_TEAM:
//                    doForwardMessage(selected.get(0), SessionTypeEnum.Team);
//                    break;
//                case REQUEST_CODE_FORWARD_PERSON:
//                    doForwardMessage(selected.get(0), SessionTypeEnum.P2P);
//                    break;
//            }
//        }
//    }
}
